/*
 * File: TUAddress.cpp
 * Author: Michael Sautter

 * Created on April 8th, 2011, 4:07p.m.
 */

#include "TigerUpdate.h"
#include <cstdlib>
#include <iostream>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>

/* Default Constructor */
TUAddress::TUAddress(){
    myAddress->sin_addr.s_addr = 0;
    myAddress->sin_family = AF_INET;
    myPortNumber = 0;
}

/* Constructor with passed address as parameter */
TUAddress::TUAddress(const char *ipAddress){
    setAddress(ipAddress);
}

/* Constructor with passed address and port as parameters */
TUAddress::TUAddress(const char *ipAddress, int port){
    setAddress(ipAddress);
    setPort(port);
}

/* Default destructor */
TUAddress::~TUAddress(){

}

bool TUAddress::operator==(TUAddress *other){
    if(myAddress == NULL) return false;
    return (myAddress->sin_addr.s_addr == other->getSockAddr()->sin_addr.s_addr);
}

/* setAddress : Uses an address passed in as a parameter to set the address. */
/*              Passed address can be in dotted decimal format, or a human   */
/*              readable address.                                            */
/*              Uses the getHostByName() function from netdb.h               */
/*              Returns a 0 on success, -1 on error                          */
int TUAddress::setAddress(const char* ipAddress){

    myAddress->sin_addr.s_addr = inet_addr(ipAddress);
    struct hostent *thehost;

    if ((int)myAddress->sin_addr.s_addr == -1) {
        if((thehost = gethostbyname(ipAddress)) == NULL){
            return -1;
        }

        myAddress->sin_addr.s_addr = *((unsigned long *) thehost->h_addr_list[0]);

    }

    return(0);
}

/* getAddress : Returns the address stored in the private myAddress variable.*/
int TUAddress::getAddress(){
    return myAddress->sin_addr.s_addr;
}

struct sockaddr_in *TUAddress::getSockAddr(){
    return myAddress;
}

/* setPort    : Uses a port number passed in as a parameter to set the port. */
/*              Returns 0 on success, -1 on error.*/
int TUAddress::setPort(int port){
    myPortNumber = port;
    if(port < 0 || port > 65535){
        std::cerr << "Error: " << port << " is outside the valid range of"
                " port numbers." << std::endl;
        return -1;
    }
    if(myPortNumber == port){
        myAddress->sin_port = htons(myPortNumber);
        return 0;
    }
    else{
        return -1;
    }
}

/* getPort    : Returns the port number stored in the private myPortNumber   */
/*              variable.                                                    */
int TUAddress::getPort(){
    return myPortNumber;
}

/* printAddress : Prints out the stored address and port number, if          */
/*                available, to the standard output                          */
void TUAddress::printAddress(){
    std::cout << "Address: " << getAddress();
    if(getPort() != 0){
        std::cout << ":" << getPort() << std::endl;
    }
    else{
        std::cout << std::endl;
    }
}
